# -*- coding:utf-8 -*-

# 为了孩子的口算跟上进度之灵活出题器
#
# Author: Caikun
# QQ: 51527966
# Github: https://github.com/MrBean818
# Gitee: https://gitee.com/wetman1
# Blog: https://blog.csdn.net/jacicson1987

import argparse
import enum
import os
import random
import xlwt
from xlwt import Workbook
import time
import datetime
import yaml
import encodings
import win32com.client as win32
import io

class Equation:
    def __init__(self):
        self.symols = []
        self.eqstr = []
        self.answer_str = []
        #random.seed(datetime.datetime.now())
    # end为和的最大值
    def random_plus(self, begin, end):
        a = random.randint(begin, end - begin)
        b = random.randint(begin, end - a)
        temptup  = (a, '+', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2],a+b))
    # end为被减数的最大值
    def random_minus(self, begin, end):
        a = random.randint(begin + 1, end)
        b = random.randint(begin, a)
        temptup = (a, '-', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2], a-b))
    
    def random_plus100(self, begin, end):
        aa = random.randint(begin, end - 1) 
        bb = random.randint(1, end - aa) 
        a = aa * 100
        b = bb * 100
        temptup  = (a, '+', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2],a+b))

    def random_plus10(self, begin, end):
        aa = random.randint(begin, end - 1) 
        bb = random.randint(1, end - aa) 
        a = aa * 10
        b = bb * 10
        temptup  = (a, '+', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2],a+b))

    def random_minus100(self, begin, end):
        aa = random.randint(begin + 1, end) 
        bb = random.randint(begin, aa) 
        a = aa * 100
        b = bb * 100
        temptup = (a, '-', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2], a-b))

    def random_minus10(self, begin, end):
        aa = random.randint(begin + 1, end)
        bb = random.randint(begin, aa)
        a = aa * 10
        b = bb * 10
        temptup = (a, '-', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2], a-b))
    # 
    def random_mult(self, begin_a, end_a, begin_b, end_b):
        a = random.randint(begin_a, end_a)
        b = random.randint(begin_b, end_b)
        temptup = (a, '×', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2], a*b))
    
    def random_mult_nto1(self, begin, end):
        a = random.randint(begin, end)
        b = random.randint(2, 9)
        temptup = (a, '×', b)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2], a*b))

    def random_div(self, c_min, c_max, a_min, a_max):
        a = random.randint(a_min, a_max)
        if a > c_min:
            min = a
        else :
            min = c_min
        c = random.randint(min, c_max)
        b = c // a
        c = a * b
        temptup = (c, '÷', a)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2], b))

    # 余数除法

    def random_div_mod(self, c_min, c_max, a_min, a_max):
        a = random.randint(a_min, a_max)
        if a > c_min:
            min = a
        else :
            min = c_min
        c = random.randint(min, c_max)
        b = c // a
        r = c % a
        temptup = (c, '÷', a)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %2d···%d" % (temptup[0],temptup[1],temptup[2], b, r))

    # 余数除法填空
    def random_div_mod_e(self, c_min, c_max, a_min, a_max):
        # if begin == 1:
        #     nb = 2
        # else:
        #     nb = begin
        # a = random.randint(nb, end)
        # b = random.randint(begin, end)
        # ra = min(a,b)
        # m = random.randint(1, ra - 1)
        # c = a * b + m
        a = random.randint(a_min, a_max)
        if a > c_min:
            min = a
        else :
            min = c_min
        c = random.randint(min, c_max)
        b = c // a
        m = c % a
        if m == 0 and a > 1:
            c += random.randint(1, a - 1)
            m = c % a
        method = random.randint(1,2)
        ## method
        ## 1: mis c
        ## 2: mis a
        if method == 1:
            temptup = ('___', '÷', a, b, m)
            self.symols = temptup
            self.eqstr = ("%s %s %2d = %s ··· %d" % 
                          (temptup[0],temptup[1],temptup[2],
                           temptup[3],temptup[4]))
            self.answer_str = ("(%2d) %s%2d=%s···%d" % 
                          (c,temptup[1],temptup[2],
                           temptup[3],temptup[4]))
        else :
            temptup = (c, '÷', '___', b, m)
            self.symols = temptup
            self.eqstr = ("%2d %s %s = %s ··· %d" % 
                          (temptup[0],temptup[1],temptup[2],
                           temptup[3],temptup[4]))
            self.answer_str = ("%2d%s (%2d) =%s···%d" % 
                          (temptup[0],temptup[1],a,
                           temptup[3],temptup[4]))

    def random_div_t(self, begin, end):
        a = random.randint(begin, end)
        b = random.randint(begin, end)
        c = a * b
        temptup = (c, '÷', a)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %d" % (temptup[0],temptup[1],temptup[2], b))

    def random_div_t_mod(self, begin, end):
        if begin == 1:
            nb = 2
        else:
            nb = begin
        a = random.randint(nb, end)
        b = random.randint(begin, end)
        ra = min(a,b)
        r = random.randint(1, ra - 1)
        c = a * b + r 
        temptup = (c, '÷', a)
        self.symols = temptup
        self.eqstr = ("%2d %s %d =" % (temptup[0],temptup[1],temptup[2]))
        self.answer_str = ("%2d%s%d= %2d···%d" % (temptup[0],temptup[1],temptup[2], b, r))

    def random_div_t_mod_e(self, begin, end):
        if begin == 1:
            nb = 2
        else:
            nb = begin
        a = random.randint(nb, end)
        b = random.randint(begin, end)
        ra = min(a,b)
        m = random.randint(1, ra - 1)
        c = a * b + m
        method = random.randint(1,2)
        ## method
        ## 1: mis c
        ## 2: mis a
        if method == 1:
            temptup = ('___', '÷', a, b, m)
            self.symols = temptup
            self.eqstr = ("%s %s %2d = %s ··· %d" % 
                          (temptup[0],temptup[1],temptup[2],
                           temptup[3],temptup[4]))
            self.answer_str = ("(%2d) %s%2d=%s···%d" % 
                          (c,temptup[1],temptup[2],
                           temptup[3],temptup[4]))
        else :
            temptup = (c, '÷', '___', b, m)
            self.symols = temptup
            self.eqstr = ("%2d %s %s = %s ··· %d" % 
                          (temptup[0],temptup[1],temptup[2],
                           temptup[3],temptup[4]))
            self.answer_str = ("%2d%s (%2d) =%s···%d" % 
                          (temptup[0],temptup[1],a,
                           temptup[3],temptup[4]))
            
    ## 加减法混合运算
    def random_mix_pm(self, begin, end):
        method_1 = random.randint(1, 2)
        method_2 = random.randint(1, 4)
        ## method_1
        ## 1: a + 
        ## 2: a -
        ## method_2
        ## 1: b + c
        ## 2: b - c
        ## 3: (b + c)
        ## 4: (b - c)
        if method_1 == 1: 
            if method_2 == 1: ## a + b + c
                a = random.randint(begin, end - 2)
                x = random.randint(2, end - a)
                b = random.randint(1, x - 1)
                c = x - b
                r = a + b + c
                temptup = (a, '+', b, '+', c)
                self.symols = temptup
                self.eqstr = ("%2d %s %d %s %d=" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4])) 
                self.answer_str = ("%2d%s%d%s%d= %d" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4], r))    
            elif method_2 == 3: ## a + (b + c)
                a = random.randint(begin, end - 2)
                x = random.randint(2, end - a)
                b = random.randint(1, x - 1)
                c = x - b
                r = a + (b + c)
                temptup = (a, '+', '(', b, '+', c, ')')
                self.symols = temptup
                self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
                self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
            elif method_2 == 2: ## a + b - c
                x = random.randint(begin + 1, end)
                c = random.randint(begin, x - 1)
                a = random.randint(begin, x - 1)
                b = x - a
                r = a + b - c
                temptup = (a, '+', b, '-', c)
                self.symols = temptup
                self.eqstr = ("%2d %s %d %s %d=" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4]))
                self.answer_str = ("%2d%s%d%s%d= %d" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4], r)) 
            elif method_2 == 4: ## a + (b - c)
                a = random.randint(begin, end - 1)
                x = random.randint(1, end - a)
                b = random.randint(x + 1, end)
                c = b - x
                r = a + (b - c)
                temptup = (a, '+', '(', b, '-', c, ')')
                self.symols = temptup
                self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
                self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
        elif method_1 == 2:
            if method_2 == 1: ## a - b + c
                a = random.randint(begin, end)
                b = random.randint(1, a - 1)
                c = random.randint(1, end - (a - b))
                r = a - b + c
                temptup = (a, '-', b, '+', c)
                self.symols = temptup
                self.eqstr = ("%2d %s %d %s %d=" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4]))
                self.answer_str = ("%2d%s%d%s%d= %d" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4], r))    
            elif method_2 == 2: ## a - b - c
                a = random.randint(begin, end)
                b = random.randint(1, a - 1)
                c = random.randint(1, (a - b))
                r = a - b - c
                temptup = (a, '-', b, '-', c)
                self.symols = temptup
                self.eqstr = ("%2d %s %d %s %d=" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4]))
                self.answer_str = ("%2d%s%d%s%d= %d" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4], r))
            elif method_2 == 3: ## a - (b + c)
                a = random.randint(begin, end)
                x = random.randint(2, a - 1)
                b = random.randint(1, x - 1)
                c = x - b
                r = a - (b + c)
                temptup = (a, '-', '(', b, '+', c, ')')
                self.symols = temptup
                self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
                self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
            elif method_2 == 4: ## a - (b - c)
                a = random.randint(begin, end)
                x = random.randint(1, a - 1)
                b = random.randint(x, end)
                c = b - x ## b - c = x
                r = a - (b - c)
                temptup = (a, '-', '(', b, '-', c, ')')
                self.symols = temptup
                self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
                self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                            (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))

    #乘法和加减法混合运算
    # begin end 乘法的乘数的范围
    # max最大和的大小
    # max > begin * end
    def random_mix_mult_pm(self, begin, end, max):
        mult_a = random.randint(begin, end)
        mult_b = random.randint(begin, end)
        method = random.randint(1, 4) 
        ## method 
        ## 1： 右+, 2：左+, 3：右-, 4：左-
        if method == 1:
            ta = random.randint(1, max - mult_a * mult_b)
            temptup = (mult_a, '×', mult_b, '+', ta)
            r = mult_a * mult_b + ta
        elif method == 2:
            ta = random.randint(1, max - mult_a * mult_b)
            temptup = ( ta, '+', mult_a, '×', mult_b,)
            r = ta + mult_a * mult_b
        elif method == 3:
            ta = random.randint(1, mult_a * mult_b)
            temptup = (mult_a, '×', mult_b, '-', ta)
            r = mult_a * mult_b - ta
        else :
            ta = random.randint(mult_a * mult_b, max)
            temptup = ( ta, '-', mult_a, '×', mult_b,)
            r = ta - mult_a * mult_b
        self.symols = temptup
        self.eqstr = ("%2d %s %d %s %d =" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4]))
        self.answer_str = ("%2d%s%d%s%d = %d" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4], r))

    ## 带括号的混合运算 乘加减
    ## a x (b + c) = 
    ## a x (b - c) = 
    ## (a + b) x c = 
    ## (a - b) x c = 
    def random_mix_mult_pm_brack(self, begin, end, max):
        mult_a = random.randint(begin, end)
        if begin == 1:
            mult_b = random.randint(begin + 1, end)
        else:
            mult_b = random.randint(begin, end)
        
        method = random.randint(1, 4) 
        ## method 
        ## 1：x(+), 2：x(-), 3:(+)x, 4(-)x
        if method == 1:
            a = random.randint(1, mult_b - 1)
            b = mult_b - a
            r = mult_a * (a + b)
            temptup = (mult_a, '×', '(', a , '+', b,')')
            self.symols = temptup
            self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r)) 
        elif method == 2:
            a = random.randint(mult_b + 1, max)
            b = a - mult_b
            temptup = (mult_a, '×', '(', a , '-', b,')')
            r = mult_a * (a - b)
            self.symols = temptup
            self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r)) 
        elif method == 3:
            a = random.randint(1, mult_b - 1)
            b = mult_b - a
            r = (a + b) * mult_a
            temptup = ('(', a , '+', b,')', '×', mult_a)
            self.symols = temptup
            self.eqstr = ("%s%d %s %d%s %s %2d =" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%s%d%s%d%s%s%2d = %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
        else:
            a = random.randint(mult_b + 1, max)
            b = a - mult_b
            r = (a - b) * mult_a
            temptup = ('(', a , '-', b,')', '×', mult_a) 
            self.symols = temptup
            self.eqstr = ("%s%d %s %d%s %s %2d =" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%s%d%s%d%s%s%2d = %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
                    
            

    #除法和加减法混合运算
    # begin end 乘法的乘数的范围
    # max 最大被减数
    # max > begin * end
    def random_mix_div_pm(self, begin, end, max):
        diva = random.randint(begin, end)
        divb = random.randint(begin, end)
        big = diva * divb
        method = random.randint(1, 4) 
        ## method 
        ## 1： 右+, 2：左+, 3：右-, 4：左-
        if method == 1:
            ta = random.randint(1, max - divb)
            temptup = (big, '÷', diva, '+', ta)
            r = big / diva + ta
        elif method == 2:
            ta = random.randint(1, max - divb)
            temptup = ( ta, '+', big, '÷', diva)
            r = ta + big / diva
        elif method == 3:
            ta = random.randint(1, divb)
            temptup = (big, '÷', diva, '-', ta) 
            r = big / diva - ta           
        else :
            ta = random.randint(divb, max)
            temptup = ( ta, '-', big, '÷', diva)
            r = ta - big / diva
        self.symols = temptup
        self.eqstr = ("%2d %s %d %s %d =" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4]))
        self.answer_str = ("%2d%s%d%s%d = %d" % (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4], r))

    ## 带括号的混合运算 除加减
    ## a / (b + c) =
    ## a / (b - c) = 
    ## (a + b) / c =
    ## (a - b) / c =
    def random_mix_div_pm_brack(self, begin, end, max):
        mult_a = random.randint(begin, end)
        if begin == 1:
            mult_b = random.randint(begin + 1, end)
        else:
            mult_b = random.randint(begin, end)
        
        diva = mult_a * mult_b
        method = random.randint(1, 4) 
        ## method 
        ## 1：÷(+) 2: ÷(-) 3: (+)÷ 4: (-)÷
        if method == 1:
            a = random.randint(1, mult_b - 1)
            b = mult_b - a
            r = diva / (a + b)
            temptup = (diva, '÷', '(', a , '+', b,')')
            self.symols = temptup
            self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
        elif method == 2 :
            a = random.randint(mult_b + 1, max)
            b = a - mult_b
            r = diva / (a - b)
            temptup = (diva, '÷', '(', a , '-', b,')')
            self.symols = temptup
            self.eqstr = ("%2d %s %s%d %s %d%s =" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%2d%s%s%d%s%d%s = %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
        elif method == 3:
            a = random.randint(1, diva - 1)
            b = diva - a
            r = (a + b) / mult_a
            temptup = ('(', a , '+', b,')', '÷', mult_a)
            self.symols = temptup
            self.eqstr = ("%s%d %s %d%s %s %2d=" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%s%d%s%d%s%s%2d= %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))
        else:
            a = random.randint(diva + 1, max)
            b = a - diva
            r = (a - b) / mult_a
            temptup = ('(', a , '-', b,')', '÷', mult_a)
            self.symols = temptup
            self.eqstr = ("%s%d %s %d%s %s %2d=" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6]))
            self.answer_str = ("%s%d%s%d%s%s%2d= %d" % 
                        (temptup[0],temptup[1],temptup[2],temptup[3],temptup[4],temptup[5],temptup[6], r))

    def compare(self, equ):
        if self.symols == equ.symols:
            return 0
        else:
            return 1
    

class CalcList:
    def __init__(self, cfg):
        self.user = ""
        self.cfg = cfg
        self.pages = cfg.pages
        self.has_answer = cfg.has_answer
        self.shuffle = cfg.shuff
        self.plus_eq = []
        self.minus_eq = []
        self.plus100_eq = []
        self.plus10_eq = []
        self.minus100_eq = []
        self.minus10_eq = []
        self.mult_eq = []
        self.mult_nto1_eq = []
        self.div_eq = []
        self.div_mod_eq = []
        self.div_mod_e_eq = []
        self.div_t_eq = []
        self.div_t_mod_eq = []
        self.div_t_mod_e_eq = []
        self.mix_pm = []
        self.mix_mult = []
        self.mix_mult_b = []
        self.mix_div = []
        self.mix_div_b = []
        self.listall = []

    def append_eq(self, eqlist, eq):
        for m in eqlist:
            if eq.compare(m) == 0:
                return -1
        eqlist.append(eq)
        return 0

    def print_eq(self, eqlist):
        for m in eqlist:
            print(m.eqstr)

    def print_all(self):
        self.print_eq(self.plus_eq)
        self.print_eq(self.minus_eq)
        self.print_eq(self.mult_eq)
        self.print_eq(self.div_eq)
        self.print_eq(self.div_mod_eq)
        self.print_eq(self.div_mod_e_eq)
        self.print_eq(self.mix_mult)
        self.print_eq(self.mix_mult_b)
        self.print_eq(self.mix_div)
        self.print_eq(self.mix_div_b)
        

    def gen_eq_plus(self, num, min , max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_plus(min, max)
            ret = self.append_eq(self.plus_eq, teq)
            if ret == 0:
                cnt = cnt + 1
    
    def gen_eq_minus(self, num, min, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_minus(min, max)
            ret = self.append_eq(self.minus_eq, teq)
            if ret == 0:
                cnt = cnt + 1 

    def gen_eq_plus100(self, num, min, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_plus100(min, max)
            ret = self.append_eq(self.plus100_eq, teq)
            if ret == 0:
                cnt = cnt + 1
    def gen_eq_plus10(self, num, min, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_plus10(min, max)
            ret = self.append_eq(self.plus10_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_minus100(self, num, min, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_minus100(min, max)
            ret = self.append_eq(self.minus100_eq, teq)
            if ret == 0:
                cnt = cnt + 1 

    def gen_eq_minus10(self, num,min, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_minus10(min, max)
            ret = self.append_eq(self.minus10_eq, teq)
            if ret == 0:
                cnt = cnt + 1 

    def gen_eq_mult(self, num, x_min_a, x_max_a, x_min_b, x_man_b):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_mult(x_min_a, x_max_a, x_min_b, x_man_b)
            ret = self.append_eq(self.mult_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_mult_nto1(self, num, x_min, x_max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_mult_nto1(x_min, x_max)
            ret = self.append_eq(self.mult_nto1_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_div(self, num, c_min, c_max, a_min, a_max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_div(c_min, c_max, a_min, a_max)
            ret = self.append_eq(self.div_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_div_mod(self, num, c_min, c_max, a_min, a_max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_div_mod(c_min, c_max, a_min, a_max)
            ret = self.append_eq(self.div_mod_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_div_mod_e(self, num, c_min, c_max, a_min, a_max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_div_mod_e(c_min, c_max, a_min, a_max)
            ret = self.append_eq(self.div_mod_e_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_div_t(self, num):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_div_t(1, 9)
            ret = self.append_eq(self.div_t_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_div_t_mod(self, num):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_div_t_mod(2, 9)
            ret = self.append_eq(self.div_t_mod_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_div_t_mod_e(self, num):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_div_t_mod_e(2, 9)
            ret = self.append_eq(self.div_t_mod_e_eq, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_mix_pm(self, num, min, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_mix_pm(min, max)
            ret = self.append_eq(self.mix_pm, teq)
            if ret == 0:
                cnt = cnt + 1
 
    def gen_eq_mix_mult(self, num, x_min, x_max, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_mix_mult_pm(x_min, x_max, max)
            ret = self.append_eq(self.mix_mult, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_mix_mult_b(self, num, x_min, x_max, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_mix_mult_pm_brack(x_min, x_max, max)
            ret = self.append_eq(self.mix_mult_b, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_mix_div(self, num, x_min, x_max, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_mix_div_pm(x_min, x_max, max)
            ret = self.append_eq(self.mix_div, teq)
            if ret == 0:
                cnt = cnt + 1

    def gen_eq_mix_div_b(self, num, x_min, x_max, max):
        cnt = 0
        while (cnt < num):
            teq = Equation()
            teq.random_mix_div_pm_brack(x_min, x_max, max)
            ret = self.append_eq(self.mix_div_b, teq)
            if ret == 0:
                cnt = cnt + 1

    def excel_to_pdf(self, bookname , pdf_path):
        """
        将 Excel 转为 PDF
        :param excel_path: 输入的 Excel 文件路径
        :param pdf_path: 输出的 PDF 文件路径
        """
        excel = win32.Dispatch("Excel.Application")
        excel.Visible = False

        # 打开 Excel 文件
        workbook = excel.Workbooks.Open(os.path.abspath(bookname))

        # 导出为 PDF
        workbook.ExportAsFixedFormat(0, os.path.abspath(pdf_path))

        # 关闭 Excel
        workbook.Close(False)
        excel.Quit()
    
    def genarate_equation(self):
        
        workbook = Workbook(encoding="utf-8")
        i = 0
        for pagelist in self.listall:
            #总题库随机打乱
            i = i + 1
            print("生成 %d 道计算题: 第%d页 --%s" % (len(pagelist), i, self.user))
            sheetname =  "Page-" + str(i) 
            self.genarate_sheet(workbook, sheetname, pagelist, 0)
            if self.has_answer:
                print("生成 %d 道计算题: 第%d页 参考答案" % (len(pagelist), i))
                sheetname =  "Page-" + str(i) + "-answer"
                self.genarate_sheet(workbook, sheetname, pagelist, 1)
    
        now = time.localtime()
        datestr = ("%02d-%02d-%02d%02d%02d-calc" % (now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec))

        bookname = datestr + ".xls"
        print("Save File: " + bookname)
        workbook.save(bookname)
        #buffer = io.BytesIO()
        #workbook.save(buffer)
        #buffer.seek(0)

        pdfname = datestr + ".pdf"
        self.excel_to_pdf(bookname, pdfname)
        # 删除临时 Excel 文件
        if os.path.exists(bookname):
            os.remove(bookname)

        return None
    
    def genarate_sheet(self, workbook, sheetname, listall, is_answer):
        sheet = workbook.add_sheet(sheetname)
        row = 0
        column = 0
        style = xlwt.XFStyle() 
        # 为样式创建字体
        font = xlwt.Font()  
        font.name = '微软雅黑' # 设置字体
        font.colour_index = 0 # 设置字体颜色
        font.height = 320 # 字体大小
        style.font = font
        #sheet.set_header_str("-- 安馨课后托管空间! -- ".encode())
        sheet.set_header_str("-- Practice to Perfect! -- ".encode())
        #footer = "安馨课后托管空间"
        #sheet.set_footer_str(footer.encode(encoding = "cp936"))
        sheet.set_footer_str("FileName:&F  -- From AnXin ".encode())
        sheet.set_left_margin(0)
        sheet.set_right_margin(0)
        sheet.set_print_centered_horz(0)


        alignment  = xlwt.Alignment()
        alignment.horz = 3     # 设置水平位置，1是左对齐，2是居中，3是右对齐
        alignment.vert = 1     # 设置垂直位置，0是左对齐，1是居中，2是右对齐
        style.alignment = alignment
        sheet.col(0).width = 27 * 256
        sheet.col(1).width = 32 * 256
        sheet.col(2).width = 33 * 256

        title_align = xlwt.Alignment()
        title_align.horz = 2     # 设置水平位置，1是左对齐，2是居中，3是右对齐
        title_align.vert = 1     # 设置垂直位置，0是左对齐，1是居中，2是右对齐
        title_style = xlwt.XFStyle() 
        title_font = xlwt.Font()  
        title_font.name = '微软雅黑' # 设置字体
        title_font.colour_index = 0 # 设置字体颜色
        title_font.height = 400 # 字体大小
        title_style.font =title_font
        title_style.alignment = title_align

        sheet.merge(0, 0, 0, 2)

        #sheet.write(0, 0, "小学四则运算 共" + str(len(listall)) + "题  " + 
        #sheetname + " --" + self.user, title_style)
        if self.user != ' ':
            sheet.write(0, 0, "小学四则运算 共" + str(len(listall)) + "题  " + sheetname + " -- " + self.user, title_style)
        else:
            sheet.write(0, 0, "小学四则运算 共" + str(len(listall)) + "题  " + sheetname, title_style)

        #sheet.write_merge(0, 0, 0, 2)
        sheet.row(1).height_mismatch = True
        sheet.row(1).height = 25 * 25
        row = 2
        line = 0
        for x in listall:
            if is_answer:
                item = x.answer_str
            else:
                item = x.eqstr
            sheet.row(row).height_mismatch = True
            sheet.row(row).height = 25 * 25
            sheet.write(row, column, item, style)
            
            if line > 0 and (line+1) % 10 == 0 and column == 2:
                row += 1
                sheet.write(row, column, " ", style)

            if column == 0:
                column = 1
            elif column == 1:
                column = 2
            elif column == 2:
                column = 0
                row += 1
                line += 1
            else:
                print("error")

    def Gen(self):
        cfg = self.cfg
        for i in range(self.cfg.pages):
            self.gen_eq_plus(cfg.plus_n, cfg.plus_min, cfg.plus_max)
            self.gen_eq_minus(cfg.minus_n, cfg.minus_min, cfg.minus_max)
            self.gen_eq_plus100(cfg.plus100_n, cfg.plus100_min // 100, cfg.plus100_max // 100)
            self.gen_eq_minus100(cfg.minus100_n, cfg.minus100_min // 100, cfg.minus100_max // 100)
            self.gen_eq_plus10(cfg.plus10_n, cfg.plus10_min // 10, cfg.plus10_max // 10)
            self.gen_eq_minus10(cfg.minus10_n, cfg.minus10_min // 10, cfg.minus10_max // 10)
            self.gen_eq_mult(cfg.mult_n, cfg.mult_min_a, cfg.mult_max_a, cfg.mult_min_b, cfg.mult_max_b)
            self.gen_eq_mult_nto1(cfg.mult_nto1_n, cfg.mult_nto1_min, cfg.mult_nto1_max)
            self.gen_eq_div(cfg.div_n, cfg.div_min_c, cfg.div_max_c, cfg.div_min_a, cfg.div_max_a)
            self.gen_eq_div_mod(cfg.div_mod_n, cfg.div_mod_min_c, cfg.div_mod_max_c,cfg.div_mod_min_a, cfg.div_mod_max_a)
            self.gen_eq_div_mod_e(cfg.div_mod_e_n, cfg.div_mod_e_min_c, cfg.div_mod_e_max_c,
                                  cfg.div_mod_e_min_a, cfg.div_mod_e_max_a)
            self.gen_eq_div_t(cfg.div_t_n)
            self.gen_eq_div_t_mod(cfg.div_t_mod_n)
            self.gen_eq_div_t_mod_e(cfg.div_t_mod_e_n)
            self.gen_eq_mix_pm(cfg.mix_pm_n, cfg.mix_pm_min, cfg.mix_pm_max)
            self.gen_eq_mix_mult(cfg.mix_mult_n, cfg.mix_mult_min, cfg.mix_mult_max, cfg.mix_mult_max_sum)
            self.gen_eq_mix_mult_b(cfg.mix_mult_b_n, cfg.mix_mult_b_min, cfg.mix_mult_b_max, cfg.mix_mult_b_max_sum)
            self.gen_eq_mix_div(cfg.mix_div_n, cfg.mix_div_min, cfg.mix_div_max, cfg.mix_div_max_sum)
            self.gen_eq_mix_div_b(cfg.mix_div_b_n, cfg.mix_div_b_min, cfg.mix_div_b_max, cfg.mix_div_b_max_sum)
            self.flush_apage()
        self.user = cfg.user
        self.genarate_equation()

    def flush_apage(self):
        listpage = (self.plus_eq + self.minus_eq + self.mult_eq + self.mult_nto1_eq + self.div_eq + self.div_mod_eq +
                    self.div_mod_e_eq + self.div_t_eq + self.div_t_mod_eq +self.div_t_mod_e_eq +
                    self.plus100_eq + self.plus10_eq + self.minus100_eq + self.minus10_eq + self.mix_pm + 
                    self.mix_mult + self.mix_div + self.mix_mult_b + self.mix_div_b)
        if self.shuffle :
            random.shuffle(listpage)
        self.listall.append([])
        it = len(self.listall)
        self.listall[it - 1] = listpage

        #self.print_all()
        self.plus_eq.clear()
        self.minus_eq.clear()
        self.mult_eq.clear()
        self.mult_nto1_eq.clear()
        self.div_eq.clear()
        self.div_mod_eq.clear()
        self.div_mod_e_eq.clear()
        self.div_t_eq.clear()
        self.div_t_mod_eq.clear()
        self.div_t_mod_e_eq.clear()
        self.mix_pm.clear()
        self.mix_mult.clear()
        self.mix_div.clear()
        self.mix_mult_b.clear()
        self.mix_div_b.clear()
        self.plus100_eq.clear()
        self.plus10_eq.clear()
        self.minus100_eq.clear()
        self.minus10_eq.clear()

class Config:
    def __init__(self):
        self.user = ""
        self.shuff = 0
        self.pages = 0
        self.has_answer = 0
        self.plus_n = 0
        self.plus_max = 0
        self.plus_min = 0
        self.minus_n = 0
        self.minus_max = 0
        self.minus_min = 0
        self.plus100_n = 0
        self.plus100_max = 0
        self.plus100_min = 0
        self.minus100_n = 0
        self.minus100_max = 0
        self.minus100_min = 0
        self.plus10_n = 0
        self.plus10_max = 0
        self.plus10_min = 0
        self.minus10_n = 0
        self.minus10_max = 0
        self.minus10_min = 0
        self.mult_n = 0
        self.mult_max_a = 0
        self.mult_min_a = 0
        self.mult_max_b = 0
        self.mult_min_b = 0        
        self.mult_nto1_n = 0
        self.mult_nto1_max = 0
        self.mult_nto1_min = 0
        self.div_n = 0
        self.div_max = 0
        self.div_min = 0
        self.div_mod_n = 0
        self.div_mod_max = 0
        self.div_mod_min = 0
        self.div_mod_e_n = 0
        self.div_mod_e_max = 0
        self.div_mod_e_min = 0
        self.div_t_n = 0
        self.div_t_mod_n = 0
        self.div_t_mode_e_n = 0
        self.mix_pm_n = 0
        self.mix_pm_max = 0
        self.mix_pm_min = 0
        self.mix_mult_n = 0
        self.mix_mult_max = 0
        self.mix_mult_min = 0
        self.mix_mult_max_sum = 0
        self.mix_div_n = 0
        self.mix_div_max = 0
        self.mix_div_min = 0
        self.mix_div_max_sum = 0
        self.mix_mult_b_n = 0
        self.mix_mult_b_max = 0
        self.mix_mult_b_min = 0
        self.mix_mult_b_max_sum = 0
        self.mix_div_b_n = 0
        self.mix_div_b_max = 0
        self.mix_div_b_min = 0
        self.mix_div_b_max_sum = 0

    def load_config(self, file):
        with open(file, 'r', encoding='utf-8') as file:
            config = yaml.safe_load(file)

        para = config['全局']
        self.shuff = para['乱序使能']
        self.pages = para['页数']
        self.has_answer = para['附答案']

        eqpa = config['加法']
        self.plus_n = eqpa['题目数']
        self.plus_max = eqpa['最大和数']
        self.plus_min = eqpa['最小加数']

        eqpa = config['减法']
        self.minus_n = eqpa['题目数']
        self.minus_max = eqpa['最大和数']
        self.minus_min = eqpa['最小加数']

        eqpa = config['整百加法']
        self.plus100_n = eqpa['题目数']
        self.plus100_max = eqpa['最大和数']
        self.plus100_min = eqpa['最小加数']   

        eqpa = config['整百减法']
        self.minus100_n = eqpa['题目数']
        self.minus100_max = eqpa['最大和数']
        self.minus100_min = eqpa['最小加数']  

        eqpa = config['整十加法']
        self.plus10_n = eqpa['题目数']
        self.plus10_max = eqpa['最大和数']
        self.plus10_min = eqpa['最小加数'] 

        eqpa = config['整十减法']
        self.minus10_n = eqpa['题目数']
        self.minus10_max = eqpa['最大和数']
        self.minus10_min = eqpa['最小加数'] 
      
        eqpa = config['乘法']
        self.mult_n = eqpa['题目数']
        self.mult_max_a = eqpa['因数a最大值']
        self.mult_min_a = eqpa['因数a最小值']
        self.mult_max_b = eqpa['因数b最大值']
        self.mult_min_b = eqpa['因数b最小值']        

        eqpa = config['多乘一']
        self.mult_nto1_n = eqpa['题目数']
        self.mult_nto1_max = eqpa['最大因数']
        self.mult_nto1_min = eqpa['最小因数']

        eqpa = config['整除除法']
        self.div_n = eqpa['题目数']
        self.div_max_c = eqpa['被除数最大值']
        self.div_min_c = eqpa['被除数最小值']
        self.div_max_a = eqpa['除数最大值']
        self.div_min_a = eqpa['除数最小值']

        eqpa = config['余数除法']
        self.div_mod_n = eqpa['题目数']
        self.div_mod_max_c = eqpa['被除数最大值']
        self.div_mod_min_c = eqpa['被除数最小值']  
        self.div_mod_max_a = eqpa['除数最大值']
        self.div_mod_min_a = eqpa['除数最小值']  

        eqpa = config['余数除法填空']
        self.div_mod_e_n = eqpa['题目数']
        self.div_mod_e_max_c = eqpa['被除数最大值']
        self.div_mod_e_min_c = eqpa['被除数最小值']  
        self.div_mod_e_max_a = eqpa['除数最大值']
        self.div_mod_e_min_a = eqpa['除数最小值']  

        eqpa = config['表内整除除法']
        self.div_t_n = eqpa['题目数']

        eqpa = config['表内余数除法']
        self.div_t_mod_n = eqpa['题目数']

        eqpa = config['表内余数除法填空']
        self.div_t_mod_e_n = eqpa['题目数']

        eqpa = config['加减混合']
        self.mix_pm_n = eqpa['题目数']
        self.mix_pm_max = eqpa['最大和数']
        self.mix_pm_min = eqpa['最小加数'] 

        eqpa = config['乘加减混合']
        self.mix_mult_n = eqpa['题目数']
        self.mix_mult_max = eqpa['最大因数']
        self.mix_mult_min = eqpa['最小因数']
        self.mix_mult_max_sum = eqpa['最大和数']

        eqpa = config['除加减混合']
        self.mix_div_n = eqpa['题目数']
        self.mix_div_max = eqpa['最大因数']
        self.mix_div_min = eqpa['最小因数']
        self.mix_div_max_sum = eqpa['最大和数']

        eqpa = config['乘加减混合带括号']
        self.mix_mult_b_n = eqpa['题目数']
        self.mix_mult_b_max = eqpa['最大因数']
        self.mix_mult_b_min = eqpa['最小因数']
        self.mix_mult_b_max_sum = eqpa['最大和数']   

        eqpa = config['除加减混合带括号']
        self.mix_div_b_n = eqpa['题目数']
        self.mix_div_b_max = eqpa['最大因数']
        self.mix_div_b_min = eqpa['最小因数']
        self.mix_div_b_max_sum = eqpa['最大和数']

        self.print_config()
    
    def print_config(self):

        print("全局:             乱序使能:", self.shuff, "，页数:", self.pages, "，附答案:", self.has_answer)
        print("加法:             题目数:", self.plus_n, "，最大和数:", self.plus_max, "，最小加数:", self.plus_min)
        print("减法:             题目数:", self.minus_n, "，最大和数:", self.minus_max, "，最小加数:", self.minus_min)
        print("整百加法:         题目数:", self.plus100_n, "，最大和数:", self.plus100_max, "，最小加数:", self.plus100_min)
        print("整百减法:         题目数:", self.minus100_n, "，最大和数:", self.minus100_max, "，最小加数:", self.minus100_min)
        print("整十加法:         题目数:", self.plus10_n, "，最大和数:", self.plus10_max, "，最小加数:", self.plus10_min)
        print("整十减法:         题目数:", self.minus10_n, "，最大和数:", self.minus10_max, "，最小加数:", self.minus10_min)
        print("乘法配置:         题目数:", self.mult_n, "，因数a最大值:", self.mult_max_a, "，因数a最小值:", self.mult_min_a, 
              "，因数b最大值:", self.mult_max_b, "，因数b最小值:", self.mult_min_b)
        print("多乘一:           题目数:", self.mult_nto1_n, "，最大因数:", self.mult_nto1_max, "，最小因数:", self.mult_nto1_min)
        print("整除除法:         题目数:", self.div_n, "，被除数最大值:", self.div_max_c, "，被除数最小值:", self.div_min_c, 
              "，除数最大值:", self.div_max_a, "，除数最小值:", self.div_min_a)
        print("余数除法:         题目数:", self.div_mod_n, "，被除数最大值:", self.div_mod_max_c, "，被除数最小值:", self.div_mod_min_c, 
              "，除数最大值:", self.div_mod_max_a, "，除数最小值:", self.div_mod_min_a)
        print("余数除法填空:     题目数:", self.div_mod_n, "，被除数最大值:", self.div_mod_max_c, "，被除数最小值:", self.div_mod_min_c, 
              "，除数最大值:", self.div_mod_max_a, "，除数最小值:", self.div_mod_min_a)
        print("表内整除除法:     题目数:", self.div_t_n)
        print("表内余数除法:     题目数:", self.div_t_mod_n)
        print("表内余数除法填空: 题目数:", self.div_t_mod_e_n)
        print("加减混合:         题目数:", self.mix_pm_n, "，最大和数:", self.mix_pm_max, "，最小加数:", self.mix_pm_min)
        print("乘加减混合:       题目数:", self.mix_mult_n, "，最大因数:", self.mix_mult_max, "，最小因数:", self.mix_mult_min, "，最大和数:", self.mix_mult_max_sum)
        print("除加减混合:       题目数:", self.mix_div_n, "，最大因数:", self.mix_div_max, "，最小因数:", self.mix_div_min, "，最大和数:", self.mix_div_max_sum)
        print("乘加减混合括号:   题目数:", self.mix_mult_b_n, "，最大因数:", self.mix_mult_b_max, "，最小因数:", self.mix_mult_b_min, "，最大和数:", self.mix_mult_b_max_sum)
        print("除加减混合括号:   题目数:", self.mix_div_b_n, "，最大因数:", self.mix_div_b_max, "，最小因数:", self.mix_div_b_min, "，最大和数:", self.mix_div_b_max_sum)
        print(" ")

def main():
    # 创建参数解析器
    parser = argparse.ArgumentParser(description='Process some files.')
    # 添加配置文件名参数
    parser.add_argument('-f', '--configfile', type=str, default='config.yaml', help='Name of the configuration file')
    parser.add_argument('-u', '--username', type=str, default=' ', help='Name of user')
    # 解析命令行参数
    args = parser.parse_args()

    # 打印配置文件名
    print('Using configuration file:', args.configfile)
    
    cfg = Config()
    cfg.user = args.username
    cfg.load_config(args.configfile)
    calist = CalcList(cfg)
    calist.Gen()
    os.system("pause")
    
if __name__ == '__main__':
    main()